package com.yunxin.yundubbo;


import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.yunxin.yundubbo.connection.DubboService;
import com.yunxin.yundubbo.properties.DubbedProperties;
import com.yunxin.yundubbo.util.ExposeInterfacesContext;
import com.yunxin.yundubbo.util.NamingServiceContext;
import jakarta.annotation.PreDestroy;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import java.net.InetAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;


@Configuration
@ComponentScan(basePackages = {"com.yunxin.yundubbo"})
@EnableConfigurationProperties(DubbedProperties.class)
public class AutoConfiguration implements ApplicationRunner {

    private Logger logger = LoggerFactory.getLogger(AutoConfiguration.class);

    private final DubbedProperties propertise;

    public AutoConfiguration(DubbedProperties propertise) {
        this.propertise=propertise;
        logger.info("Dubbo start！");
    }

    @Getter
    private NamingService namingService;

    private Instance instance;

    private static final DubboService dubboService = new DubboService(1, 10);



    public void register() {
        try {
            logger.info("Dubbo注册nacos！");
            //配置服务器连接信息
            Properties properties = new Properties();
            properties.put("serverAddr", propertise.getRegisConfig().getRegisAddress()); // Nacos Server地址
            properties.put("username", propertise.getRegisConfig().getUserName());
            properties.put("password", propertise.getRegisConfig().getPassWorld());
            if (propertise.getRegisConfig().getNameSpaces() != null) {
                properties.put("namespaces", propertise.getRegisConfig().getNameSpaces());
            }
            logger.info("参数配置：{}", properties);
            //创建NamingService实例
            namingService = NacosFactory.createNamingService(properties);
            NamingServiceContext.FUTURE.complete(namingService);
            // 获取本机IP地址
            InetAddress localHost = InetAddress.getLocalHost();
            logger.info("service port :{}", propertise.getPort());
            instance = getInstance(localHost, propertise.getPort());
            // 5. 执行注册！指定一个唯一的服务名
            List<String> list = ExposeInterfacesContext.list();
            for (String serverName : list) {
                logger.info("service name :{}", serverName);
                namingService.registerInstance(serverName, instance);
                logger.info("服务{}实例注册成功！", serverName);
            }
            // 7. 在适当的时候（如服务关闭时），记得注销实例
            // namingService.deregisterInstance(serviceName, instance);
        } catch (NacosException e) {
            System.err.println("注册服务时发生Nacos异常: " + e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            System.err.println("发生其他异常: " + e.getMessage());
            e.printStackTrace();
        }
    }

    @PreDestroy
    public void deregister() {
        try {
            if (namingService != null && instance != null) {
                List<String> list = ExposeInterfacesContext.list();
                for (String serverName : list) {
                    namingService.deregisterInstance(serverName, instance);
                }
                dubboService.shutdown();
                logger.info("服务实例注销成功！");
            }
        } catch (NacosException e) {
            logger.error("服务注销失败", e);
        }
    }

    /**
     * 服务注册实例
     *
     * @param localHost
     * @param port
     * @return
     */
    private static Instance getInstance(InetAddress localHost, int port) {
        Instance instance = new Instance();
        instance.setIp(localHost.getHostAddress()); // 你的服务实例IP
        instance.setPort(port);          // 你的服务实例端口
        instance.setWeight(1.0);         // 权重，默认为1
        instance.setClusterName("DEFAULT"); // 集群名，默认为"DEFAULT"
        instance.setEphemeral(true);     // 是否为临时实例，默认为true
        // 4. （可选）设置元数据，用于存储自定义信息（如版本号、环境等）
        Map<String, String> metadata = new HashMap<>();
        metadata.put("version", "1.0");
        metadata.put("env", "dev");
        instance.setMetadata(metadata);
        dubboService.start(localHost.getHostAddress(), port);
        return instance;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        register();
    }
}
